package com.acme.bankapp.domain.bank;

import com.acme.bankapp.exceptions.NotEnoughFundsException;
import com.acme.bankapp.exceptions.OverDraftLimitExceededException;

/**
 * This is checking variant of particular implementation of abstract account
 * 
 * @author Anton Kotov
 * 
 */
public class CheckingAccount extends AbstractAccount {

	private double overdraft;

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		long temp;
		temp = Double.doubleToLongBits(overdraft);
		result = prime * result + (int) (temp ^ (temp >>> 32));
		return result;
	}

	@Override
	public String toString() {
		return super.toString() + " -> CheckingAccount [overdraft=" + overdraft
				+ "]";
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj) {
			return true;
		}
		if (obj == null) {
			return false;
		}
		if (!(obj instanceof CheckingAccount)) {
			return false;
		}
		CheckingAccount other = (CheckingAccount) obj;
		if (Double.doubleToLongBits(overdraft) != Double
				.doubleToLongBits(other.overdraft)) {
			return false;
		}
		return true;
	}

	public CheckingAccount(final int id, final double balance,
			final double overdraft) {
		super(id, balance);

		if (balance + overdraft < 0.) {
			throw new IllegalArgumentException();
		}

		this.overdraft = overdraft;
	}

	public void withdraw(final double amount)
			throws OverDraftLimitExceededException {
		if (amount <= 0.) {
			throw new IllegalArgumentException();
		}
		try {
			super.withdraw(amount);
		} catch (NotEnoughFundsException e) {
			throw new OverDraftLimitExceededException("Failed to withdraw: account is " + this, e);
		}
		assert (balance + overdraft >= 0.) : "balance + overdraft is negative";
	}

	@Override
	public double maximumAmountToWithdraw() {
		return getBalance() + overdraft;
	}
}
